namespace Wiki.Web.Mvc
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
    public sealed class SingleEntityCacheAttribute : ActionFilterAttribute
    {
        public SingleEntityCacheAttribute()
        {
        }

        public SingleEntityCacheAttribute(int days, int hours, int minutes, int seconds)
        {
            this.Days = days;
            this.Hours = hours;
            this.Minutes = minutes;
            this.Seconds = seconds;
        }

        public int Days
        {
            get;
            private set;
        }

        public int Hours
        {
            get;
            private set;
        }

        public int Minutes
        {
            get;
            private set;
        }

        public int Seconds
        {
            get;
            private set;
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (null == filterContext)
            {
                throw new ArgumentNullException("filterContext");
            }

            base.OnActionExecuted(filterContext);

            FileInfo file = filterContext.ViewPageFileInfo();
            if (null != file)
            {
                HttpResponseBase response = filterContext.HttpContext.Response;
                response.Cache.SetCacheability(HttpCacheability.Public);

                TimeSpan expiry = new TimeSpan(this.Days, this.Hours, this.Minutes, this.Seconds);
                if (expiry > TimeSpan.Zero)
                {
                    TimeSpan year = new TimeSpan(365, 0, 0, 0);
                    response.Cache.SetExpires(DateTime.UtcNow.Add((expiry < year) ? expiry : year));
                }

                response.AddFileDependency(file.FullName);
                response.Cache.SetLastModifiedFromFileDependencies();
                response.Cache.SetETagFromFileDependencies();
            }
        }
    }
}